/*--------------------------------------------------------------
 * Library of date routines
 *-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <locale.h>

#include "datelib.h"

/* #define DRIVER 1 */

static const int Days_in_month[13] = {
    0,
    31, 28, 31,     /* Jan, Feb, Mar */
    30, 31, 30,     /* Apr, May, Jun */
    31, 31, 30,     /* Jul, Aug, Sep */
    31, 30, 31      /* Oct, Nov, Dec */
};

/* same as above but for a leap year */
static const int Days_in_month_leap[13] = {
    0,
    31, 29, 31,     /* Jan, Feb, Mar */
    30, 31, 30,     /* Apr, May, Jun */
    31, 31, 30,     /* Jul, Aug, Sep */
    31, 30, 31      /* Oct, Nov, Dec */
};

static const char *Day_name[7] = {
    "Sunday",   "Monday",
    "Tuesday",  "Wednesday",
    "Thursday", "Friday",
    "Saturday"
};

static const char *Day_name_abbrev[7] = {
    "Sun",  "Mon",
    "Tue",  "Wed",
    "Thu",  "Fri",
    "Sat"
};

static const char *Month_name[13] = {
    "",
    "January",  "February", "March",
    "April",    "May",      "June",
    "July",     "August",   "September",
    "October",  "November", "December"
};

static const char *Month_name_abbrev[13] = {
    "",
    "Jan",  "Feb",  "Mar",
    "Apr",  "May",  "Jun",
    "Jul",  "Aug",  "Sep",
    "Oct",  "Nov",  "Dec"
};


#ifndef YES
#define YES 1
#define NO  0
#endif

/*--------------------------------------------------------------
 * Accepts pointers to two date structures and returns the
 * difference in days between them as a long int. Negative if
 * the first date is earlier, positive if it is later. No error
 * return is possible, so programmers must make sure the dates
 * are valid.
 *-------------------------------------------------------------*/
long DateDiff(struct tm *d1, struct tm *d2)
{
    return (DateToDayNumber(d1) - DateToDayNumber(d2));
}

/*--------------------------------------------------------------
 * Returns a long which contains the number of days since
 * Jan 1, AD 1; returns -1L on error. See text for observations
 * on the use of this function.
 *-------------------------------------------------------------*/
long DateToDayNumber(struct tm *date)
{
    long day_num;
    int  mm, yy;

    if (IsDateValid(date) == NO)
        return (-1L);

    yy = date->tm_year;
    mm = date->tm_mon + 1;

    /* get all the regular days in preceding years */
    day_num = (yy - 1) * 365L;

    /* now get the leap years */
    day_num += (yy - 1) / 4L;

    /*
     * now back out the century years that are not leap:
     * this would be all century years that are
     * not evenly divisible by 400: 1700, 1800, 1900, 2100...
     */
    day_num -= (yy - 1) / 100L;
    day_num += (yy - 1) / 400L;

    /*
     * before 1582 all century years were leap, so adjust for
     * this. If year is > 1582, then just add 12 days for years
     * 100, 200, 300, 500, 600, 700, 900, 1000, 1100, 1300, 1400
     * and 1500. Otherwise, calculate it.
     */
    if (yy - 1 > 1582L)
        day_num += 12L;
    else {
        day_num += (yy - 1) / 100L;
        day_num -= (yy - 1) / 400L;
    }

    /* now, add the days elapsed in the year so far */
    if (IsYearLeap (date->tm_year) == NO)
        while (--mm)
            day_num += Days_in_month[mm];
    else
        while (--mm)
            day_num += Days_in_month_leap[mm];

    /* add days in current month for the year being evaluated */
    day_num += date->tm_mday;

    /*
     * now adjust for the 10 days cut out of the calendar when
     * the change was made to the Gregorian calendar. This change
     * reflects the jump from October 4 to October 15, 1582, a
     * deletion of 10 days.
     */
    if (day_num > 577737L)
        day_num -= 10L;

    return (day_num);
}

/*--------------------------------------------------------------
 * Converts a day number into an actual date.
 *-------------------------------------------------------------*/
int DayNumberToDate(long int day_num, struct tm *date)
{
    int dd, mm, yy, i;
    long days_left;

    if (day_num > 577737L)
        day_num += 10L;

    yy = (int)(day_num / 365);
    days_left = day_num % 365L;

    /* prior to 1700, all years evenly divisible by 4 are leap */
    if (yy < 1700)
        days_left -= (yy / 4);
    else {
        days_left -= (yy / 4);      /* deduct leap years */
        days_left += (yy / 100);    /* add in century years */
        days_left -= (yy / 400);    /* deduct years / 400 */
        days_left -= 12;            /* deduct century years that
                                       were leap before 1700 */
    }

    /* make sure days left is > 0 */
    while (days_left <= 0) {
        if (IsYearLeap(yy) == YES) {
            yy -= 1;
            days_left += 366;
        } else {
            yy -= 1;
            days_left += 365;
        }
    }

    /*
     * yy holds the number of elapsed years.
     * So, add 1 for the current year.
     */
    yy += 1;

    /*
     * now deduct the days in each month, starting
     * from January to find month and day of month.
     * adjust for leap year, of course.
     */
    dd = (int)days_left;
    mm = 0;

    if (IsYearLeap(yy) == YES) {
        for (i = 1; i <= 12; i++) {
            mm = i;
            if (dd <= Days_in_month_leap[i])
                break;
            else
                dd -= Days_in_month_leap[i];
        }
    } else {
        for (i = 1; i <= 12; i++) {
            mm = i;
            if (dd <= Days_in_month[i])
                break;
            else
                dd -= Days_in_month[i];
        }
    }

    if (LoadDateStruct(date, yy, mm, dd) == -1)
        return (-1);
    else
        return (0);
}

/*--------------------------------------------------------------
 * Returns an integer from 0-6 signifying the day of the week,
 * where 0 = Sunday and 6 = Saturday. Returns -1 on error.
 *-------------------------------------------------------------*/
int DayOfWeek(struct tm *date)
{
    long day_num = DateToDayNumber(date);

    if (day_num < 0)
        return (-1);

    return ((int)((day_num % 7) + 5) % 7);
}

/*--------------------------------------------------------------
 * Returns an integer from 1-366 signifying the day of the year.
 * where 1 is Jan 1, 365 or 366 is Dec 31, and -1 is an error.
 *-------------------------------------------------------------*/
int DayOfYear(struct tm *date)
{
    struct tm jan1;

    if (LoadDateStruct(&jan1, date->tm_year, 1, 1) == -1)
        return (-1);

    return ((int)(DateDiff(date, &jan1) + 1));
}

/*--------------------------------------------------------------
 * Returns YES if date is valid, otherwise returns NO.
 *-------------------------------------------------------------*/
int IsDateValid(struct tm *date)
{
    if (date->tm_mon < 0 || date->tm_mon > 11)   /* per ANSI */
        return (NO);

    if (date->tm_year < 1)
        return (NO);

    if (IsYearLeap (date->tm_year) == NO)
        if (date->tm_mday < 1 ||
             date->tm_mday > Days_in_month[date->tm_mon + 1])
            return (NO);
        else if (date->tm_mday < 1 ||
                 date->tm_mday > Days_in_month_leap[date->tm_mon + 1])
            return (NO);

    return (YES);
}

/*--------------------------------------------------------------
 * Returns YES if time is valid, otherwise returns NO.
 *-------------------------------------------------------------*/
int IsTimeValid(struct tm *date)
{
    if (date->tm_hour < 0 || date->tm_hour > 23)
        return (NO);

    if (date->tm_min < 0 || date->tm_min > 59)
        return (NO);

    /*
     * Technically speaking, ANSI allows for minutes with
     * 61 or 62 seconds for leap seconds that are added
     * with little warning by astronomical societies to
     * reflect slight changes in the earth's rotation.
     * For reasons discussed in the text, however, we
     * observe only the 60-second minute.
     */
    if (date->tm_sec < 0 || date->tm_sec > 59)
        return (NO);

    return (YES);
}

/*--------------------------------------------------------------
 * Returns YES or NO depending on whether a year is leap or not
 *-------------------------------------------------------------*/
int IsYearLeap(int year)
{
    if (year % 4 != 0)    /* if year not divisible by 4... */
        return (NO);      /* it's not leap */

    if (year < 1582)      /* all years divisible by 4 were */
        return (YES);     /* leap prior to 1582            */

    if (year % 100 != 0)  /* if year divisible by 4, */
        return (YES);     /* but not by 100, it's leap */

    if (year % 400 != 0)  /* if year divisible by 100, */
        return (NO);      /* but not by 400, it's not leap */
    else
        return (YES);     /* if divisible by 400, it's leap */
}

/*--------------------------------------------------------------
 * Loads a date passed as three integers into a tm structure.
 * Returns 0 on success, -1 on error.
 *-------------------------------------------------------------*/
int LoadDateStruct(struct tm *date, int yy, int mm, int dd)
{
    date->tm_year = yy;
    date->tm_mon = mm - 1; /* for compatibility w/ ANSI C */
    date->tm_mday = dd;

    if (IsDateValid(date) == NO)
        return (-1);
    else
        return (0);
}

/*--------------------------------------------------------------
 * Loads time into an existing tm structure.
 * Returns 0 on success, -1 on error
 *-------------------------------------------------------------*/
int LoadTimeStruct(struct tm *date, int hh, int mm, int ss)
{
    date->tm_hour = hh;
    date->tm_min = mm;
    date->tm_sec = ss;

    if (IsTimeValid(date) == NO)
        return (-1);
    else
        return (0);
}

/*--------------------------------------------------------------
 * TimeDiff() operates like difftime(), however it can accept
 * times before Jan 1, 1900. No error return.
 *-------------------------------------------------------------*/
double TimeDiff(struct tm *t1, struct tm *t2)
{
    long day_num;
    double d1, d2;

    day_num = DateToDayNumber(t1);
    d1 = day_num * 86400.0 + t1->tm_hour * 3600.0 +
         t1->tm_min * 60.0 + t1->tm_sec;

    day_num = DateToDayNumber(t2);
    d2 = day_num * 86400.0 + t2->tm_hour * 3600.0 +
         t2->tm_min * 60.0 + t2->tm_sec;

    return (d1 - d2);
}

/*--------------------------------------------------------------
 * Operates like strftime() except:
 *  a) it returns -1 on error;
 *  b) strftime() expects tm_year to be 2 digits and so always
 *     adds 1900 to the year, while TimeSprintf() believes the
 *     year to be the actual year: 94 is AD 94 and so does not
 *     add 1900.
 *-------------------------------------------------------------*/
int TimeSprintf(char *string, int max_size,
                char *format, struct tm *ptm)
{
    char *pf;
    int  i, j;

    int  yy;        /* scratch variable for year */
    int  mon;       /* our internal use of the month is 1-12 */
    char *buffer;   /* where the output string goes */

    mon = ptm->tm_mon + 1;

    buffer = malloc(1024);   /* largest likely output string */
    if (buffer == NULL)
        return (-1);

    i = 0;      /* where we are in the output string */

    for (pf = format; *pf != '\0' && i < 1024; pf++) {
        if (*pf != '%')
            buffer[i++] = *pf;
        else {
            switch (*(++pf)) {
                /*--- day of the week: Sunday, Monday...---*/
            case 'a':               /* 3-letter weekday */
                j = DayOfWeek(ptm);
                strncpy(buffer + i, Day_name_abbrev[j], 3);
                i += 3;
                break;

            case 'A':               /* full weekday */
                j = DayOfWeek(ptm);
                strcpy(buffer + i, Day_name[j]);
                while (*(buffer + i) != '\0')
                    i++;
                break;

            case 'w':               /* weekday as a digit */
                j = DayOfWeek(ptm);
                buffer[i++] = j + '0';
                break;

                /*--- day of the month: 1, 2, 3...---*/

            case 'd':               /* day as a number */
                buffer[i++] = ptm->tm_mday / 10 + '0';
                buffer[i++] = ptm->tm_mday % 10 + '0';
                break;

            case 'm':               /* month as a number */
                buffer[i++] = mon / 10 + '0';
                buffer[i++] = mon % 10 + '0';
                break;

                /*--- month ---*/

            case 'b':               /* 3-letter month */
                strncpy(buffer + i, Month_name_abbrev[mon], 3);
                i += 3;
                break;

            case 'B':               /* full month name */
                strcpy(buffer + i, Month_name[mon]);
                while (*(buffer + i) != '\0')
                    i++;
                break;

                /*--- year ---*/

            case 'Y':               /* year with century: 1994 */
                yy = ptm->tm_year;

                if (yy < 0) {
                    buffer[i++] = '-';
                    yy = -yy;
                }

                if (yy > 9999) {
                    buffer[i++] = yy / 10000 + '0';
                    yy %= 10000;
                }

                if (yy > 999) {
                    buffer[i++] = yy / 1000 + '0';
                    yy %= 1000;
                }

                if (yy > 99) {
                    buffer[i++] = yy / 100 + '0';
                    yy %= 100;
                }

                buffer[i++] = yy / 10 + '0';
                buffer[i++] = yy % 10 + '0';
                break;

            case 'y':               /* year without century: 94 */
                yy = ptm->tm_year;

                if (yy < 0) {
                    buffer[i++] = '-';
                    yy = -yy;
                }

                if (yy > 100)
                    yy %= 100;

                buffer[i++] = yy / 10 + '0';
                buffer[i++] = yy % 10 + '0';
                break;

            case 'x':               /* locale-specific date */
            {
                char s[18];

                TimeSprintf(s, 18, "%a, %b %d, %Y", ptm);
                strcpy(buffer + i, s);
                i += strlen(s);
            }
                break;

                /*--- time in numbers ---*/

            case 'I':               /* hour on 12-hr clock */
            {
                int hour;

                if (ptm->tm_hour > 12)
                    hour = ptm->tm_hour - 12;
                else
                    hour = ptm->tm_hour;

                buffer[i++] = hour / 10 + '0';
                buffer[i++] = hour % 10 + '0';
            }
                break;

            case 'H':               /* hour on 24-hr clock */
                buffer[i++] = ptm->tm_hour / 10 + '0';
                buffer[i++] = ptm->tm_hour % 10 + '0';
                break;

            case 'M':               /* minute as a number */
                buffer[i++] = ptm->tm_min / 10 + '0';
                buffer[i++] = ptm->tm_min % 10 + '0';
                break;

            case 'S':               /* seconds as a number */
                buffer[i++] = ptm->tm_sec / 10 + '0';
                buffer[i++] = ptm->tm_sec % 10 + '0';
                break;

            case 'X':               /* time string: hh:mm:ss */
            {
                char s[9];

                TimeSprintf(s, 9, "%H:%M:%S", ptm);
                strcpy(buffer + i, s);
                i += 8;
            }
                break;

                /*--- miscellaneous ---*/

            case 'c':               /* date and time */
            {
                char s[28];

                TimeSprintf(s, 28, "%b %d %H:%M:%S %Y", ptm);
                strcpy(buffer + i, s);
                i += strlen(s);
            }
                break;

            case 'j':               /* day of the year: 1-366 */
            {
                int day_of_year;

                day_of_year = DayOfYear (ptm);

                if (day_of_year < 10)
                    buffer[i++] = day_of_year + '0';
                else {
                    if (day_of_year > 99) {
                        buffer[i++] = day_of_year / 100 + '0';
                        day_of_year %= 100;
                    }

                    buffer[i++] = day_of_year / 10 + '0';
                    buffer[i++] = day_of_year % 10 + '0';
                }
            }
                break;

            case 'p':               /* AM or PM */
                if (ptm->tm_hour < 12)
                    buffer[i++] = 'A';
                else
                    buffer[i++] = 'P';
                buffer[i++] = 'M';
                break;

            case 'U':               /* Sunday week of year */
            case 'W':               /* Monday week of year */
            {
                int day_of_year,
                    day_of_week,
                    sunday_week;

                struct tm jan1;

                int jan1_dow;       /* jan 1 day of week */

                day_of_year = DayOfYear(ptm);
                day_of_week = DayOfWeek(ptm);

                LoadDateStruct(&jan1, ptm->tm_year, 1, 1);
                jan1_dow = DayOfWeek(&jan1);

                if (jan1_dow != 0)
                    day_of_year -= (7 - jan1_dow);

                if (day_of_year < 1)
                    sunday_week = 0;
                else {
                    sunday_week = 1;
                    sunday_week += (day_of_year - 1) / 7;
                }

                if (*pf == 'W')   /* if Monday week */
                    if (day_of_week < 1)
                        sunday_week -= 1;

                if (sunday_week > 9) {
                    buffer[i++] = (sunday_week / 10) + '0';
                    sunday_week %= 10;
                }

                buffer[i++] = sunday_week + '0';
            }
                break;

            case 'Z':               /* the time zone */
            {
                char *temp;

                temp = setlocale(LC_TIME, NULL);
                if (temp == NULL)
                    buffer[i++] = 'C';
                else {
                    strcpy(buffer + i, temp);
                    i += strlen(temp);
                }
            }
                break;

            case '%':               /* the percent sign */
                buffer[i++] = '%';
                break;

            default:
                strcpy(buffer + i, "Error in TimeSprintf() ");
                i += 23;
            }
        }
    }
    buffer[i] = '\0';

    strncpy(string, buffer, max_size);
    free(buffer);

    if (i <= max_size)
        return (i);
    else
        return (0);
}

#ifdef DRIVER

int script_date_to_tms(char *, struct tm *);
int script_time_to_tms(char *, struct tm *);

int main(int argc, char *argv[])
{
    FILE *infile;

    char *p, str[40], str2[40];
    int  action, i;
    long day_num;

    time_t timer;
    struct tm *tms,
              *tms2;

    struct tm tm1, tm2;

    tms = &tm1;
    tms2= &tm2;

    if (argc < 2) {    /* if no args, just print the date */
        timer = time(NULL);
        tms = localtime(&timer);

        TimeSprintf(str, 40, "%m-%d-%Y at %H:%M:%S", tms);
        printf("Today is %s\n", str);

        return (EXIT_SUCCESS);
    }

    if (argc == 3) {
        long start, end, test, count;
        start = atol(argv[1]);
        end = atol(argv[2]);

        if (start < 1 || (start + end) < 1) {
            printf("Usage: datelib start-day-num "
                   "how-many-dates\n");
            return (0);
        }

        count = 0L;
        day_num = start;

        while (1) {
            DayNumberToDate(day_num, tms);
            test = DateToDayNumber(tms);
            if (test != day_num) {
                count += 1;
                printf("%ld is %d-%d-%d but becomes %ld\n",
                       day_num,
                       tms->tm_mon, tms->tm_mday,
                       tms->tm_year,
                       test);
            }

            if (start < end) {
                if (day_num < end)
                    day_num += 1;
                else
                    break;
            } else if (start > end) {
                if (day_num > end)
                    day_num -= 1;
                else
                    break;
            }
        }

        printf("\n%01ld error(s) occurred\n", count);

        return (0);
    }

    /* only valid arg is a test script; so read and play it */
    infile =  fopen(argv[1], "rt");
    if (infile == NULL) {
        printf("Cannot open %s\n", argv[1]);
        return (EXIT_FAILURE);
    }

    while (!feof(infile)) {
        if (fgets(str, 40, infile) == NULL)
            break;

        action = *str;
        p = str + 1;

        switch (action) {
        case ';':   /* comment line */
            continue;

        case 'a':   /* exercise TimeSprintf() */
        case 'A':
            i = script_date_to_tms(p, tms);
            if (i < 0)
                continue;
            p++;
            while (*p != ' ' && *p != '\n')
                p++;
            i = script_time_to_tms(p, tms);
            if (i < 0)
                continue;

            tms2->tm_year = tms->tm_year - 1900;
            tms2->tm_mon = tms->tm_mon;
            tms2->tm_mday = tms->tm_mday;
            tms2->tm_hour = tms->tm_hour;
            tms2->tm_min = tms->tm_min;
            tms2->tm_sec = tms->tm_sec;
            mktime(tms2);

            printf("Format               TimeSprintf             strftime\n\n");

            TimeSprintf(str, 40, "%a %A", tms);
            strftime(str2, 40, "%a %A", tms2);
            printf("%%a %%A      %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%b %B", tms);
            strftime(str2, 40, "%b %B", tms2);
            printf("%%b %%B      %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%d", tms);
            strftime(str2, 40, "%d", tms2);
            printf("%%d         %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%y %Y", tms);
            strftime(str2, 40, "%y %Y", tms2);
            printf("%%y %%Y      %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%H/%I:%M:%S %p", tms);
            strftime(str2, 40, "%H/%I:%M:%S %p", tms2);
            printf("%%H/I%%M%%S%%p %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%U %W", tms);
            strftime(str2, 40, "%U %W", tms2);
            printf("%%U %%W      %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%j %m %%", tms);
            strftime(str2, 40, "%j %m %%", tms2);
            printf("%%j %%m %%    %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%x %X", tms);
            strftime(str2, 40, "%x %X", tms2);
            printf("%%X %%x       %20s        %20s\n", str, str2);

            TimeSprintf(str,  40, "%c %Z", tms);
            strftime(str2, 40, "%c %Z", tms2);
            printf("%%c %%Z       %20s        %20s\n", str, str2);

            break;

        case 'f':   /* difference between dates */
        case 'F':
            i = script_date_to_tms(p, tms);
            if (i < 0)
                continue;
            p++;
            while (*p != ' ' && *p != '\n')
                p++;
            i = script_date_to_tms(p, tms2);
            day_num = DateDiff(tms, tms2);
            TimeSprintf(str, 40, "%m-%d-%Y", tms);
            printf("%s is %ld days from ", str, day_num);
            TimeSprintf(str, 40, "%m-%d-%Y", tms2);
            printf("%s\n", str);
            break;

        case 'n':   /* convert day number to date */
        case 'N':
            while (*p != '\n' && !isdigit(*p))
                p++;

            day_num = atol(p);
            DayNumberToDate(day_num, tms);
            TimeSprintf(str, 40, "%m-%d-%Y", tms);
            printf("%ld is %s\n", day_num, str);
            break;

        case 't':   /* print today's date */
        case 'T':
            timer = time(NULL);
            tms = localtime(&timer);

            TimeSprintf(str, 40, "%m-%d-%Y at %H:%M:%S", tms);
            printf("Today is %s, ", str);

            tms->tm_year += 1900;
            LoadDateStruct(tms2, 1, 1, 1);
            LoadTimeStruct(tms2, 0, 0, 0);
            printf("%g secs elapsed in the modern era\n",
                   TimeDiff(tms, tms2));
            break;

        case 'u':   /* Sunday/Monday week count */
        case 'U':
            i = script_date_to_tms(p, tms);
            if (i < 0)
                continue;

            tms2->tm_year = tms->tm_year - 1900;
            tms2->tm_mon = tms->tm_mon;
            tms2->tm_mday = tms->tm_mday;
            tms2->tm_hour = 9;
            tms2->tm_min = 10;
            tms2->tm_sec = 11;
            mktime(tms2);

            printf("Format               TimeSprintf                   strftime\n\n");

            TimeSprintf(str,  40, "%U %W", tms);
            strftime(str2, 40, "%U %W", tms2);
            printf("%%U %%W      %20s        %20s\n", str, str2);
            break;

        case 'w':   /* day of week */
        case 'W':
            i = script_date_to_tms(p, tms);
            if (i < 0)
                continue;
            i = DayOfWeek(tms);
            day_num = DateToDayNumber(tms);
            printf("%d-%d-%d is %s day num: %ld\n",
                   tms->tm_mon + 1, tms->tm_mday,
                   tms->tm_year,
                   Day_name[i], day_num);
            break;

        default:
            printf("Error: %s\n", str);
            break;
        }

    }
    return (EXIT_SUCCESS);
}

/*--------------------------------------------------------------
 * reads a script date in mm-dd-yyyy order and loads it into
 * a tm structure pointed to by tms.
 *-------------------------------------------------------------*/
int script_date_to_tms (char *p, struct tm *tms)
{
    int yy, mm, dd;
    char *orig_p = p;

    while (*p != '\n' && !isdigit(*p))
        p++;

    mm = atoi(p);
    while (*p != '\n' && isdigit(*p))
        p++;

    dd = atoi(++p);
    while (*p != '\n' && isdigit(*p))
        p++;

    yy = atoi(++p);

    if (LoadDateStruct(tms, yy, mm, dd) == -1) {
        printf("Error: %s\n", orig_p);
        return (-1);
    }

    return (0);
}

int script_time_to_tms(char *p, struct tm *tms)
{
    int hh, mm, ss;

    while (*p != '\n' && !isdigit(*p))
        p++;

    hh = atoi(p);
    while (*p != '\n' && isdigit(*p))
        p++;

    mm = atoi(++p);
    while (*p != '\n' && isdigit(*p))
        p++;

    ss = atoi(++p);

    if (hh < 0 || hh > 23)
        return (-1);
    else
        tms->tm_hour = hh;

    if (mm < 0 || hh > 59)
        return (-1);
    else
        tms->tm_min = mm;

    if (ss < 0 || ss > 59)
        return (-1);
    else
        tms->tm_sec = ss;

    return (0);
}
#endif
